package com.bcx.wind.workflow.imp.cmd.repositorycmd.processmodule;

import com.bcx.wind.workflow.access.QueryFilter;
import com.bcx.wind.workflow.entity.WindProcess;
import com.bcx.wind.workflow.entity.WindProcessModule;
import com.bcx.wind.workflow.interceptor.Command;
import com.bcx.wind.workflow.interceptor.CommandContext;
import com.bcx.wind.workflow.pojo.ProcessModule;
import com.bcx.wind.workflow.support.Assert;
import com.bcx.wind.workflow.support.ObjectHelper;

import java.util.LinkedList;
import java.util.List;

import static com.bcx.wind.workflow.core.constant.Constant.ROOT_MODULE;
import static com.bcx.wind.workflow.message.ErrorCode.QUERY_EMPTY;
import static com.bcx.wind.workflow.message.ErrorCode.ROOT_MODULE_CANNOT_DELETED;
import static com.bcx.wind.workflow.message.ErrorCode.UPDATE_OPERATE_LACK_PRIMARY;

/**
 * 删除流程定义模块命令
 *
 * @author zhanglei
 */
public class DeleteProcessModuleCommand implements Command<Integer> {

    /**
     * 主键
     */
    private String id;


    private CommandContext commandContext;

    /**
     * 需要删除的模块集合
     */
    private List<WindProcessModule> processModules = new LinkedList<>();

    public DeleteProcessModuleCommand(String id){
        this.id = id;
    }


    @Override
    public Integer executor(CommandContext context) {
        try{
            this.commandContext = context;
            return execute();

        }catch (Exception e) {
            return 0;
        }
    }

    private Integer execute() {
        //校验主键
        Assert.notEmptyError(UPDATE_OPERATE_LACK_PRIMARY,this.id,"processModule");
        //校验是否为根目录 根模块不可删除
        Assert.isTrueError(ROOT_MODULE_CANNOT_DELETED,ROOT_MODULE.equals(this.id));
        //校验模块是否存在
        WindProcessModule processModule = this.commandContext.access().selectProcessModuleById(this.id);
        Assert.notEmptyError(QUERY_EMPTY,processModule,"processModule",this.id);

        //递归删除
        deleteOperate(processModule);
        //更新缓存数据
        ProcessModule module = this.commandContext.repositoryService()
                .selectDataWindProcessModule(processModule.getSystem());
        this.commandContext.getConfiguration().changeProcessModuleCache(module);
        return 1;
    }


    private void deleteOperate(WindProcessModule processModule) {
        //构建需要删除的模块集合
        buildNeedDeleteModule(processModule);
        //循环遍历校验是否可以删除
        for(WindProcessModule module : this.processModules){
            String moduleId = module.getId();
            //查询该模块下所有的流程定义
            QueryFilter filter = new QueryFilter()
                    .setProcessModule(moduleId);
            List<WindProcess> windProcesses = this.commandContext.access().selectProcessList(filter);
            //调用资源服务，删除流程定义，是否可以删除在资源服务中有校验
            if(!ObjectHelper.isEmpty(windProcesses)){
                for(WindProcess process : windProcesses){
                    this.commandContext.repositoryService().removeByProcessId(process.getId());
                }
            }

            //删除模块
            this.commandContext.access().deleteProcessModule(moduleId);
        }
    }


    /**
     * 查询需要删除的所有模块
     */
    private void buildNeedDeleteModule(WindProcessModule processModule){
        this.processModules.add(processModule);
        List<WindProcessModule> childs = this.commandContext.access().selectProcessModuleByParentId(processModule.getId());
        if(!ObjectHelper.isEmpty(childs)){
            for(WindProcessModule module: childs){
                buildNeedDeleteModule(module);
            }
        }
    }
}
